package cn.ultrarisk.scadmin.manager.biz.solr.dao;

import cn.ultrarisk.mybatis.extension.domain.Page;
import cn.ultrarisk.mybatis.extension.query.Query;
import cn.ultrarisk.mybatis.extension.query.Updater;
import cn.ultrarisk.scadmin.manager.biz.solr.dto.CollectionSchema;
import cn.ultrarisk.scadmin.manager.biz.solr.entity.SolrCollection;
import cn.ultrarisk.scadmin.manager.biz.solr.entity.SolrReplica;
import cn.ultrarisk.scadmin.manager.biz.zookeeper.dao.ZkNodeDAO;
import cn.ultrarisk.scadmin.manager.biz.zookeeper.entity.ZkNode;
import cn.ultrarisk.scadmin.manager.biz.zookeeper.operator.ZookeeperOperator;
import cn.ultrarisk.scadmin.manager.support.BaseDAO;
import cn.ultrarisk.scadmin.manager.util.CollectionUtil;
import cn.ultrarisk.scadmin.manager.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.*;

/**
 * solr集合数据操作类
 *
 * @author sevendlong(lin23871@163.com)
 * @date 2014/3/28
 * @since V1.0
 */
@Repository
public class SolrCollectionDAO extends BaseDAO<SolrCollection, Integer> {
    @Autowired
    private SolrReplicaDAO solrReplicaDAO;
    @Autowired
    private ZkNodeDAO zkNodeDAO;
    @Autowired
    private ZookeeperOperator zookeeperOperator;

    /**
     * 构造器
     */
    public SolrCollectionDAO() {
        super(SolrCollection.class, SolrCollection.COLUMN_PROPERTY_MAP);
    }

    public SolrCollection create(String name, String config, Boolean allowCommit, Boolean allowRollback, Integer maxStart, Integer maxLimit, String remark) {
        SolrCollection collection = new SolrCollection();
        collection.setName(name);
        collection.setConfig(config);
        collection.setRouter("implicit");
        collection.setAllowCommit(allowCommit != null ? allowCommit : false);
        collection.setAllowRollback(allowRollback != null ? allowRollback : false);
        collection.setMaxStart(maxStart);
        collection.setMaxLimit(maxLimit);
        collection.setRemark(remark);
        collection.setAvailable(true);
        collection.setUpdateTime(System.currentTimeMillis());
        create(collection);
        return collection;
    }

    public void update(Integer id, Boolean allowCommit, Boolean allowRollback, Integer maxStart, Integer maxLimit, String remark) {
        Updater updater = Updater.update(SolrCollection.ALLOW_COMMIT, allowCommit).addField(SolrCollection.ALLOW_ROLLBACK, allowRollback)
                .addField(SolrCollection.MAX_START, maxStart).addField(SolrCollection.MAX_LIMIT, maxLimit)
                .addField(SolrCollection.REMARK, remark);
        update(id, updater);
    }

    public SolrCollection getByName(String name, String... tableColumns) {
        return get(Query.query(SolrCollection.NAME, name), tableColumns);
    }

    public String getName(Integer id) {
        SolrCollection collection = get(id, SolrCollection.NAME);
        return collection != null ? collection.getName() : null;
    }

    public Map<Integer, String> getNameMap(Collection<Integer> ids) {
        Map<Integer, String> nameMap = new HashMap<Integer, String>();
        if (CollectionUtil.isNotEmpty(ids)) {
            List<SolrCollection> collections = findByIds(ids, SolrCollection.ID, SolrCollection.NAME);
            if (CollectionUtil.isNotEmpty(collections)) {
                for (SolrCollection collection : collections) {
                    nameMap.put(collection.getId(), collection.getName());
                }
            }
        }
        return nameMap;
    }

    public Map<String, Integer> getIdMap(Collection<String> names) {
        Map<String, Integer> idMap = new HashMap<String, Integer>();
        if (CollectionUtil.isNotEmpty(names)) {
            List<SolrCollection> collections = findList(Query.inQuery(SolrCollection.NAME, names), SolrCollection.ID, SolrCollection.NAME);
            if (CollectionUtil.isNotEmpty(collections)) {
                for (SolrCollection collection : collections) {
                    idMap.put(collection.getName(), collection.getId());
                }
            }
        }
        return idMap;
    }

    public List<SolrCollection> findList(Integer nodeId, Boolean available) {
        List<Integer> collectionIds = null;
        if (nodeId != null) {
            Query query = Query.query(SolrReplica.NODE_ID, nodeId);
            query.addGroup(SolrReplica.COLLECTION_ID);
            collectionIds = solrReplicaDAO.findColumn(query, SolrReplica.COLLECTION_ID, true, true);
            if (CollectionUtil.isEmpty(collectionIds)) {
                return new ArrayList<SolrCollection>();
            }
        }
        Query query = Query.query(SolrCollection.AVAILABLE, available).in(SolrCollection.ID, collectionIds);
        query.addSort(SolrCollection.NAME, Query.Direction.ASC);
        return findList(query);
    }

    public Page<SolrCollection> findPage(String name, int pageNo, int pageSize) {
        Query query = Query.likeFullQuery(SolrCollection.NAME, name);
        query.addSort(SolrCollection.NAME, Query.Direction.ASC);
        return findPage(query, pageNo, pageSize);
    }

    public CollectionSchema getSchema(Integer collectionId) {
        SolrCollection collection = get(collectionId, SolrCollection.CONFIG);
        if (collection != null && StringUtil.isNotEmpty(collection.getConfig())) {
            ZkNode zkNode = zkNodeDAO.getByPath(collection.getConfig() + "/schema.xml", 0);
            if (zkNode != null && StringUtil.isNotEmpty(zkNode.getData())) {
                return CollectionSchema.fromXml(zkNode.getData());
            }
        }
        return null;
    }

    public CollectionSchema getSchemaFromZk(Integer collectionId) {
        SolrCollection collection = get(collectionId, SolrCollection.CONFIG);
        if (collection != null && StringUtil.isNotEmpty(collection.getConfig())) {
            String schemaXml = zookeeperOperator.getData(collection.getConfig() + "/schema.xml", null);
            if (StringUtil.isNotEmpty(schemaXml)) {
                return CollectionSchema.fromXml(schemaXml);
            }
        }
        return null;
    }
}
